home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / thrust-s.53 / thrust-s / thrust / src / things.c < prev    next >
C/C++ Source or Header  |  1995-11-06  |  13KB  |  680 lines

  1.  
  2. /* Written by Peter Ekberg, peda@lysator.liu.se */
  3.  
  4. #include <stdlib.h>
  5. #include <values.h>
  6. #include <math.h>
  7. #include "thrust.h"
  8.  
  9. word nrthings=0;
  10. word nrsliders=0;
  11. word nrbarriers=0;
  12. word nrrestartpoints=0;
  13.  
  14. bullet bullets[maxbullets];
  15. fragment fragments[maxfragments];
  16. thing things[maxthings];
  17. slider sliders[maxsliders];
  18. barrier barriers[maxbarriers];
  19. restartpoint restartpoints[maxrestartpoints];
  20.  
  21. word spacestation;
  22. word ssx,ssy,scount;    /* Spacestation-variables */
  23. word ssblip;
  24.  
  25. void
  26. newslider(x,y,type)
  27.      int x,y,type;
  28. {
  29.   sliders[nrsliders].x1=x;
  30.   sliders[nrsliders].y1=y;
  31.   sliders[nrsliders].type=type;
  32.   sliders[nrsliders].dir=type%3;
  33.   sliders[nrsliders].match=0;
  34.   sliders[nrsliders].active=0;
  35.   sliders[nrsliders++].next=NULL;
  36. }
  37.  
  38. int
  39. majorbutton(button)
  40.      int button;
  41. {
  42.   if(((buttondata *)things[button].data)->major==-1)
  43.     return(button);
  44.   else
  45.     return(((buttondata *)things[button].data)->major);
  46. }
  47.  
  48. void
  49. newthing(x,y,px,py,type,data)
  50.      int x,y,px,py,type;
  51.      void *data;
  52. {
  53.   int life;
  54.  
  55.   switch(type) {
  56.   case 1:       /* Fuel */
  57.     life=140;
  58.     break;
  59.   default:
  60.     life=2;
  61.   }
  62.   things[nrthings].alive=life;
  63.   things[nrthings].x=x;
  64.   things[nrthings].y=y;
  65.   things[nrthings].px=px;
  66.   things[nrthings].py=py;
  67.   things[nrthings].type=type;
  68.   things[nrthings].data=data;
  69.   things[nrthings++].score=0;
  70. }
  71.  
  72. void
  73. animatesliders(void)
  74. {
  75.   slider *s=sliders;
  76.   int i;
  77.  
  78.   for(i=0; i<nrsliders; i++, s++)
  79.     if(s->active) {
  80.       switch(s->stage) {
  81.       case 0:
  82.     if(!(s->count&7)) {
  83.       switch(s->type) {
  84.       case 7:
  85.         writeblock(s->x1+(s->count>>3), s->y1, 233);
  86.         break;
  87.       case 8:
  88.         writeblock(s->x1-(s->count>>3), s->y1, 236);
  89.         break;
  90.       case 10:
  91.         writeblock(s->x1, s->y1+(s->count>>3), 255);
  92.         break;
  93.       case 11:
  94.         writeblock(s->x1, s->y1-(s->count>>3), 254);
  95.         break;
  96.       }
  97.     }
  98.     else if(!(s->count&3)) {
  99.       switch(s->type) {
  100.       case 7:
  101.         writeblock(s->x1+(s->count>>3), s->y1, 32);
  102.         break;
  103.       case 8:
  104.         writeblock(s->x1-(s->count>>3), s->y1, 32);
  105.         break;
  106.       case 10:
  107.         writeblock(s->x1, s->y1+(s->count>>3), 32);
  108.         break;
  109.       case 11:
  110.         writeblock(s->x1, s->y1-(s->count>>3), 32);
  111.         break;
  112.       }
  113.     }
  114.     s->count++;
  115.     if(s->count >= ((abs(s->x1-s->x2)+abs(s->y1-s->y2)+1) << 3)-1) {
  116.       s->count=0;
  117.       s->stage=1;
  118.     }
  119.     break;
  120.       case 1:
  121.     s->count++;
  122.     if(s->count>500) {
  123.       s->count=0;
  124.       s->stage=2;
  125.     }
  126.     break;
  127.       case 2:
  128.     if(!(s->count&7)) {
  129.       switch(s->type) {
  130.       case 7:
  131.         writeblock(s->x2-(s->count>>3), s->y1, 233);
  132.         break;
  133.       case 8:
  134.         writeblock(s->x2+(s->count>>3), s->y1, 236);
  135.         break;
  136.       case 10:
  137.         writeblock(s->x1, s->y2-(s->count>>3), 255);
  138.         break;
  139.       case 11:
  140.         writeblock(s->x1, s->y2+(s->count>>3), 254);
  141.         break;
  142.       }
  143.     }
  144.     else if(!(s->count&3)) {
  145.       switch(s->type) {
  146.       case 7:
  147.         writeblock(s->x2-(s->count>>3), s->y1, 224);
  148.         break;
  149.       case 8:
  150.         writeblock(s->x2+(s->count>>3), s->y1, 224);
  151.         break;
  152.       case 10:
  153.         writeblock(s->x1, s->y2-(s->count>>3), 224);
  154.         break;
  155.       case 11:
  156.         writeblock(s->x1, s->y2+(s->count>>3), 224);
  157.         break;
  158.       }
  159.     }
  160.     s->count++;
  161.     if(s->count >= ((abs(s->x1-s->x2)+abs(s->y1-s->y2)+1) << 3)-1)
  162.       s->active=0;
  163.     break;
  164.       }
  165.     }
  166. }
  167.  
  168. void
  169. startupsliders(int button)
  170. {
  171.   slider *s;
  172.  
  173.   s=((buttondata *)things[button].data)->sliders;
  174.  
  175.   while(s) {
  176.     if(s->active) {
  177.       switch(s->stage) {
  178.       case 1:
  179.     s->count=0;
  180.     break;
  181.       case 2:
  182.     s->count=(((abs(s->x1-s->x2)+abs(s->y1-s->y2)+1) << 3)-1) - s->count-7;
  183.     if(s->count<0)
  184.       s->count=0;
  185.     s->stage=0;
  186.     break;
  187.       default:
  188.     break;
  189.       }
  190.     }
  191.     else {
  192.       s->active=1;
  193.       s->stage=0;
  194.       s->count=0;
  195.     }
  196.     s=s->next;
  197.   }
  198. }
  199.  
  200. restartpoint *
  201. atbarrier(word bx, word by)
  202. {
  203.   int i;
  204.  
  205.   for(i=0; i<nrbarriers; i++)
  206.     if((barriers[i].x==bx) && (barriers[i].y==by))
  207.       return(barriers[i].restart);
  208.   return(NULL);
  209. }
  210.  
  211. void
  212. deletething(tp,dx,dy,sx,sy)
  213.      thing *tp;
  214.      int dx,dy,sx,sy;
  215. {
  216.   int tx,ty,i,j;
  217.  
  218.   tx=(*tp).px;
  219.   ty=(*tp).py;
  220.   (*tp).alive=0;
  221.  
  222.   switch((*tp).type)
  223.     {
  224.     case 1:        /* Fuel */
  225.       for(i=0; i<2; i++)
  226.     for(j=0; j<2; j++)
  227.       writeblock(tx+i, ty+j, 32);
  228.       break;
  229.     case 2:        /* Spacestation */
  230.       spacestation=0;
  231.       countdown=1000;
  232.       for(i=0; i<3; i++)
  233.     for(j=0; j<3; j++)
  234.       writeblock(tx+i, ty+j, 32);
  235.       break;
  236.     case 3:             /* Bunkers */
  237.       writeblock(tx,   ty,   32);
  238.       writeblock(tx+1, ty,   32);
  239.       writeblock(tx+2, ty,   32);
  240.       writeblock(tx+2, ty+1, 32);
  241.       break;
  242.     case 4:
  243.       writeblock(tx,   ty+1, 32);
  244.       writeblock(tx,   ty,   32);
  245.       writeblock(tx+1, ty,   32);
  246.       writeblock(tx+2, ty,   32);
  247.       break;
  248.     case 5:
  249.       writeblock(tx,   ty+1, 32);
  250.       writeblock(tx+1, ty+1, 32);
  251.       writeblock(tx+2, ty+1, 32);
  252.       writeblock(tx+2, ty,   32);
  253.       break;
  254.     case 6:
  255.       writeblock(tx,   ty,   32);
  256.       writeblock(tx,   ty+1, 32);
  257.       writeblock(tx+1, ty+1, 32);
  258.       writeblock(tx+2, ty+1, 32);
  259.       break;
  260.     }
  261. }
  262.  
  263. void
  264. newbullet(x,y,vx,vy,dir,owner)
  265.      word x,y;
  266.      int vx,vy;
  267.      word dir;
  268.      int owner;
  269. {
  270.   static word nr=0;
  271.  
  272.   bullets[nr].life=60;
  273.   bullets[nr].x=x;
  274.   bullets[nr].y=y;
  275.   bullets[nr].vx=vx;
  276.   bullets[nr].vy=vy;
  277.   bullets[nr].dir=dir;
  278.   bullets[nr++].owner=owner;
  279.  
  280.   if(nr==maxbullets)
  281.     nr=0;
  282. }
  283.  
  284. void
  285. wrapbullets()
  286. {
  287.   bullet *bulletptr;
  288.   int l;
  289.  
  290.   for(l=0, bulletptr=bullets; l<maxbullets; l++, bulletptr++)
  291.     if((*bulletptr).life)
  292.       (*bulletptr).y+=(PBILDY-leny3)<<3;
  293. }
  294.  
  295. void
  296. unwrapbullets()
  297. {
  298.   bullet *bulletptr;
  299.   int l;
  300.  
  301.   for(l=0, bulletptr=bullets; l<maxbullets; l++, bulletptr++)
  302.     if((*bulletptr).life)
  303.       (*bulletptr).y-=PBILDY<<3;
  304. }
  305.  
  306. void
  307. movebullets()
  308. {
  309.   int l;
  310.   bullet *bulletptr;
  311.  
  312.   for(l=0, bulletptr=bullets; l<maxbullets; l++, bulletptr++)
  313.     if((*bulletptr).life) {
  314.       (*bulletptr).life--;
  315.       (*bulletptr).x=((*bulletptr).x+(lenx<<6)+
  316.               (*bulletptr).vx)%(lenx<<6);
  317.       (*bulletptr).y=((*bulletptr).y+(leny<<6)+
  318.               (*bulletptr).vy)%(leny<<6);
  319.     }
  320. }
  321.  
  322. word
  323. crashtype(type)
  324.      word type;
  325. {
  326.   switch(type) {
  327.   case 1:      /* Fuel */
  328.   case 2:      /* Spacestation */
  329.   case 3:      /* 3-6 Bunkers */
  330.   case 4:
  331.   case 5:
  332.   case 6:
  333.   case 7:      /* 7-8 Buttons */
  334.   case 8:
  335.     return(4);
  336.   }
  337.   return(0);
  338. }
  339.  
  340. int
  341. inloadcontact(x,y)
  342.      int x,y;
  343. {
  344.   int dx,dy;
  345.   int dist;
  346.   int res=0;
  347.   int angle;
  348.   int sp,spr;
  349.  
  350.   dx=x-(loadbx<<3)-2;
  351.   dy=(loadby<<3)-y+2;
  352.   dist=dx*dx+dy*dy;
  353.   if(dist<1024) {
  354.     res=1-loadcontact;
  355.   }
  356.   else if(dist>=1024 && loadcontact) {
  357.     loaded=1;
  358.     if(abs(dx)<=abs(dy)) {
  359.       if(dy>=0) {
  360.     if(dx>=0)
  361.       alpha=256-arcsinus[dx];
  362.     else
  363.       alpha=256+arcsinus[-dx];
  364.       }
  365.       else if(dx>=0)
  366.     alpha=768+arcsinus[dx];
  367.       else
  368.     alpha=768-arcsinus[-dx];
  369.     }
  370.     else if(dy>=0) {
  371.       if(dx>=0)
  372.     alpha=arcsinus[dy];
  373.       else
  374.     alpha=512-arcsinus[dy];
  375.     }
  376.     else if(x>=0)
  377.       alpha=-arcsinus[-dy];
  378.     else
  379.       alpha=512+arcsinus[-dy];
  380.     angle=256-(int)(atan2(speedx,-speedy)*512/PI)-(int)alpha;
  381.     sp=hypot(speedx,speedy);    
  382.     deltaalpha=sp*sinus2[(angle)&1023]>>8;
  383.     deltaalpha=min(deltaalpha,16384);
  384.     deltaalpha=max(deltaalpha,-16384);
  385.     spr=sp*sinus2[(angle+256)&1023]>>8;
  386.     speedx=spr*sinus2[(alpha+256)&1023]>>9;
  387.     speedy=-spr*sinus2[(alpha)&1023]>>9;
  388.     loadcontact=0;
  389.   }
  390.   return(res);
  391. }
  392.  
  393. int
  394. resonablefuel(x,y,l)
  395.      int x,y,l;
  396. {
  397.   thing *tp;
  398.   int dx,dy;
  399.  
  400.   tp=&things[l];
  401.   dx=x-(int)(*tp).x;
  402.   dy=(int)(*tp).y-y;
  403.   if(dx>(int)(lenx3>>1))
  404.     dx=lenx3-dx;
  405.   if(-dx>(int)(lenx3>>1))
  406.     dx=-lenx3+dx;
  407.   return(dx>-10 && dx<9 && dy>5 && dy<60);
  408. }
  409.  
  410. int
  411. closestfuel(x,y)
  412.      int x,y;
  413. {
  414.   word i,witch=0;
  415.   thing *thingptr;
  416.   int dx,dy;
  417.   int minimum=MAXINT,d;
  418.   int hit=0;
  419.  
  420.   for(i=0, thingptr=things; i<nrthings; i++, thingptr++)
  421.     if((*thingptr).type==1 && (*thingptr).alive>1) {
  422.       dx=abs((int)x-(int)(*thingptr).x);
  423.       dy=abs((int)y-(int)(*thingptr).y);
  424.       if(dx>(lenx3>>1))
  425.     dx-=lenx3;
  426.       dy*=3;
  427.       d=dx*dx+dy*dy;
  428.       if(d<minimum) {
  429.     minimum=d;
  430.     witch=i;
  431.     hit=1;
  432.       }
  433.     }
  434.   return(hit?witch:-1);
  435. }
  436.  
  437. int
  438. closestbutton(x,y)
  439.      int x,y;
  440. {
  441.   word i,witch=0;
  442.   thing *thingptr;
  443.   int dx,dy;
  444.   int minimum=MAXINT,d;
  445.   int hit=0;
  446.  
  447.   for(i=0, thingptr=things; i<nrthings; i++, thingptr++)
  448.     if((*thingptr).type>=7 && (*thingptr).type<=8) {
  449.       dx=abs((int)x-(int)(*thingptr).x);
  450.       dy=abs((int)y-(int)(*thingptr).y);
  451.       if(dx>(lenx>>1))
  452.     dx-=lenx;
  453.       d=dx*dx+dy*dy;
  454.       if(d<minimum) {
  455.     minimum=d;
  456.     witch=i;
  457.     hit=1;
  458.       }
  459.     }
  460.   return(hit?witch:-1);
  461. }
  462.  
  463. void
  464. hit(x,y,crash,owner)
  465.      word x,y,crash,owner;
  466. {
  467.   word i,witch=0;
  468.   thing *thingptr;
  469.   long dx,dy;
  470.   long minimum=MAXLONG,d;
  471.   int hit=0;
  472.   int kill=1;
  473.  
  474.   for(i=0, thingptr=things; i<nrthings; i++, thingptr++)
  475.     if((*thingptr).alive>1 && crashtype((*thingptr).type)==crash) {
  476.       dx=(int)x-(int)(*thingptr).x;
  477.       dy=(int)y-(int)(*thingptr).y;
  478.       d=(long)dx*dx+(long)dy*dy;
  479.       if(d<minimum) {
  480.     minimum=d;
  481.     witch=i;
  482.     hit=1;
  483.       }
  484.     }
  485.   if(hit) {
  486.     explodething(&things[witch]);
  487.     switch(things[witch].type) {
  488.     case 2:
  489.       ssblip+=10;
  490.       if(ssblip>100)
  491.     things[witch].alive=1;  /* Dying */
  492.       break;
  493.     case 7:                     /* Cannot kill buttons */
  494.     case 8:
  495.       startupsliders(majorbutton(witch));
  496.       break;
  497.     default:
  498.       things[witch].alive=1;    /* Dying */
  499.       break;
  500.     }
  501.     if(kill) {
  502.     }
  503.     if(owner)
  504.       switch(things[witch].type) {
  505.       case 1:
  506.     things[witch].score=150;
  507.     break;
  508.       case 3:
  509.       case 4:
  510.       case 5:
  511.       case 6:
  512.     things[witch].score=700;
  513.     break;
  514.       }
  515.   }
  516. }
  517.  
  518. void
  519. bunkerfirebullet(b)
  520.      thing *b;
  521. {
  522.   int dir;
  523.  
  524.   dir=random()%16;
  525.   switch((*b).type) {
  526.   case 3:
  527.     dir=(dir-3)&31;
  528.     newbullet(((*b).x<<3)+14,((*b).y<<3)-68,
  529.           sinus[(dir+8)&31]>>3,-sinus[dir]>>3,
  530.           dir>>1,0);
  531.     break;
  532.   case 4:
  533.     dir=(dir+3)&31;
  534.     newbullet(((*b).x<<3)-26,((*b).y<<3)-68,
  535.           sinus[(dir+8)&31]>>3,-sinus[dir]>>3,
  536.           dir>>1,0);
  537.     break;
  538.   case 5:
  539.     dir=(dir-14)&31;
  540.     newbullet(((*b).x<<3)+14,((*b).y<<3)+44,
  541.           sinus[(dir+8)&31]>>3,-sinus[dir]>>3,
  542.           dir>>1,0);
  543.     break;
  544.   case 6:
  545.     dir=(dir+12)&31;
  546.     newbullet(((*b).x<<3)-26,((*b).y<<3)+44,
  547.           sinus[(dir+8)&31]>>3,-sinus[dir]>>3,
  548.           dir>>1,0);
  549.     break;
  550.   }
  551. }
  552.  
  553. void
  554. bunkerfirebullets()
  555. {
  556.   int l;
  557.   thing *thingptr;
  558.  
  559.   for(l=0, thingptr=things; l<nrthings; l++, thingptr++)
  560.     if((*thingptr).alive)
  561.       if((*thingptr).type>2 && (*thingptr).type<7)
  562.     if(!(random()%256))
  563.       bunkerfirebullet(thingptr);
  564. }
  565.  
  566. int
  567. killdyingthings()
  568. {
  569.   int l;
  570.   thing *thingptr;
  571.   int res;
  572.  
  573.   res=0;
  574.   for(l=0, thingptr=things; l<nrthings; l++, thingptr++)
  575.     if((*thingptr).alive==1) {
  576.       deletething(thingptr,pblockx,pblocky,bblockx,bblocky);
  577.       res+=(*thingptr).score;
  578.     }
  579.  
  580.   return(res);
  581. }
  582.  
  583. void
  584. newfragment(x,y)
  585.      word x,y;
  586. {
  587.   static word nr=0;
  588.   int dir;
  589.   int speed;
  590.  
  591.   dir=random()%32;
  592.   speed=random()%48+16;
  593.   fragments[nr].life=60;
  594.   fragments[nr].x=x;
  595.   fragments[nr].y=y;
  596.   fragments[nr].vx=(speed*sinus[(dir+8)&31])>>11;
  597.   fragments[nr++].vy=(-speed*sinus[dir])>>11;
  598.  
  599.   if(nr==maxfragments)
  600.     nr=0;
  601. }
  602.  
  603. void
  604. explodething(thingptr)
  605.      thing *thingptr;
  606. {
  607.   int i;
  608.  
  609.   for(i=0; i<30; i++) {
  610.     newfragment((thingptr->x<<3)-30+random()%61,
  611.         (thingptr->y<<3)-30+random()%61);
  612.   }
  613. }
  614.  
  615. void
  616. explodeship(void)
  617. {
  618.   int i;
  619.  
  620.   for(i=0; i<50; i++) {
  621.     newfragment((x+((154+shipdx)<<3)+random()%61)%(lenx3<<3),
  622.         (y+(( 82+shipdy)<<3)+random()%61)%(leny3<<3));
  623.     if(loaded)
  624.       newfragment((x+((161-((252-loadpoint)*sinus2[(alpha+256)&1023])/2016)<<3)
  625.            +random()%61)%(lenx3<<3),
  626.           (y+(( 89+((252-loadpoint)*sinus2[alpha])/2016)<<3)
  627.            +random()%61)%(leny3<<3));
  628.   }
  629. }
  630.  
  631. void
  632. wrapfragments()
  633. {
  634.   fragment *fragmentptr;
  635.   int l;
  636.  
  637.   for(l=0, fragmentptr=&fragments[0]; l<maxfragments; l++, fragmentptr++)
  638.     if((*fragmentptr).life)
  639.       (*fragmentptr).y+=(PBILDY-leny3)<<3;
  640. }
  641.  
  642. void
  643. unwrapfragments()
  644. {
  645.   fragment *fragmentptr;
  646.   int l;
  647.  
  648.   for(l=0, fragmentptr=&fragments[0]; l<maxfragments; l++, fragmentptr++)
  649.     if((*fragmentptr).life)
  650.       (*fragmentptr).y-=PBILDY<<3;
  651. }
  652.  
  653. void
  654. movefragments()
  655. {
  656.   int l;
  657.   fragment *fragmentptr;
  658.  
  659.   for(l=0, fragmentptr=&fragments[0]; l<maxfragments; l++, fragmentptr++)
  660.     if((*fragmentptr).life) {
  661.       (*fragmentptr).life--;
  662.       (*fragmentptr).x=((*fragmentptr).x+(lenx<<6)+
  663.               (*fragmentptr).vx)%(lenx<<6);
  664.       (*fragmentptr).y=((*fragmentptr).y+(leny<<6)+
  665.               (*fragmentptr).vy)%(leny<<6);
  666.     }
  667. }
  668.  
  669. word
  670. livefragments()
  671. {
  672.   int l;
  673.   fragment *fragmentptr;
  674.  
  675.   for(l=0, fragmentptr=&fragments[0]; l<maxfragments; l++, fragmentptr++)
  676.     if(fragmentptr->life)
  677.       return(1);
  678.   return(0);
  679. }
  680.